﻿using System;
using System.Linq;
using System.Web.Mvc;
using CodeContribBlog.Data;
using CodeContribBlog.Web.Mvc.ViewModels;

namespace CodeContribBlog.Web.Mvc.Controllers
{
	public class GadgetController : BlogController
	{
		[ChildActionOnly]
		//[OutputCache(Duration = 60, VaryByParam = "BlogId")]
		public ActionResult ArchivedPosts()
		{
			var now = DateTime.UtcNow;

			var posts = BlogContext.Posts
				.WhereIsPublic()
				.Where(p => p.PublishedAt.Year < now.Year || p.PublishedAt.Year == now.Year && p.PublishedAt.Month <= now.Month)
				.Select(p => new
					             {
						             Count = 1,
						             p.PublishedAt.Year,
						             p.PublishedAt.Month
					             }).GroupBy(x => new
						                             {
							                             x.Year,
							                             x.Month
						                             }).Select(g => new ArchivedPostsViewModel
							                                            {
								                                            Count = g.Sum(x => x.Count),
								                                            Month = g.Key.Month,
								                                            Year = g.Key.Year
							                                            }).OrderByDescending(x => x.Year).ThenByDescending(x => x.Month).ToList();

			return View("ArchivedPosts", posts);
		}

		[ChildActionOnly]
		//[OutputCache(Duration = 60, VaryByParam = "BlogId")]
		public ActionResult FuturePosts()
		{
			var now = DateTime.UtcNow;

			var posts = BlogContext.Posts.Where(p => !p.IsDeleted && p.PublishedAt > now)
				.OrderBy(p => p.PublishedAt)
				.Take(5).Select(p => new FuturePostViewModel
					                     {
						                     PublishedAt = p.PublishedAt,
						                     Title = p.Title
					                     }).ToList();

			return View("FuturePosts", posts);
		}

		public ActionResult List()
		{
			return View("List");
		}

		[ChildActionOnly]
		//[OutputCache(Duration = 60, VaryByParam = "BlogId")]
		public ActionResult RecentComments()
		{
			var now = DateTime.UtcNow;

			var comments = BlogContext.Comments
				.Where(c => !c.Post.IsDeleted && c.Post.PublishedAt <= now)
				.OrderByDescending(c => c.CreatedAt)
				.Take(5).Select(c => new RecentCommentViewModel
					                     {
						                     Author = c.Author,
						                     Body = c.Body,
						                     CommentId = c.Id,
						                     CreatedAt = c.CreatedAt,
						                     PostSlug = c.Post.Slug,
						                     PostId = c.Post.Id,
						                     PostTitle = c.Post.Title,
						                     Url = c.Url
					                     }).ToList();

			return View("RecentComments", comments);
		}

		[ChildActionOnly]
		//[OutputCache(Duration = 60, VaryByParam = "BlogId")]
		public ActionResult Statistics()
		{
			var statistics = BlogContext.Posts
				                 .WhereIsPublic()
				                 .Select(p => new
					                              {
						                              CommentCount = p.Comments.Count(),
						                              PostCount = 1
					                              }).GroupBy(x => "constant").Select(g => new StatisticsViewModel
						                                                                      {
							                                                                      CommentCount = g.Sum(x => x.CommentCount),
							                                                                      PostCount = g.Sum(x => x.PostCount)
						                                                                      }).FirstOrDefault() ?? new StatisticsViewModel();

			return View("Statistics", statistics);
		}

		[ChildActionOnly]
		//[OutputCache(Duration = 60, VaryByParam = "BlogId")]
		public ActionResult Tags()
		{
			var now = DateTime.UtcNow;
			var mostRecentTag = new DateTime(now.Year - 1, now.Month, 1, 0, 0, 0);

			var tags = BlogContext.Posts
				.SelectMany(p => p.Tags, (p, t) => new
					                                   {
						                                   Count = 1,
						                                   LastSeenAt = p.PublishedAt,
						                                   t.Name,
						                                   t.Slug
					                                   }).GroupBy(x => new
						                                                   {
							                                                   x.Name,
							                                                   x.Slug
						                                                   }).Select(g => new
							                                                                  {
								                                                                  Count = g.Sum(x => x.Count),
								                                                                  LastSeenAt = g.Max(x => x.LastSeenAt),
								                                                                  g.Key.Name,
								                                                                  g.Key.Slug
							                                                                  }).Where(x => x.Count > Blog.MinimumNumberOfPostsForSignificantTag && x.LastSeenAt > mostRecentTag).OrderBy(x => x.Name).Select(x => new TagViewModel
								                                                                                                                                                                                                       {
									                                                                                                                                                                                                       Count = x.Count,
									                                                                                                                                                                                                       Name = x.Name,
									                                                                                                                                                                                                       Slug = x.Slug
								                                                                                                                                                                                                       }).ToList();

			return View("Tags", tags);
		}
	}
}